package me.numark.providers;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

import me.numark.utils.Settings;

/**
 * Created by tian on 14-9-18:上午7:53.
 */
public class NumarkProvider extends ContentProvider {

    private DatabaseHelper mHelper;

    public static final UriMatcher sMatcher;

    public static final int ID_NEWS = 0;

    public static final int ID_NEWS_ITEM = 1;

    public static final int ID_FEED = 10;

    public static final int ID_FEED_ITEM = 11;

    public static final int ID_DIALOGS = 2;

    public static final int ID_KVS = 3;

    public static final int ID_MESSAGES = 4;

    public static final int ID_USERS = 5;

    public String currUid = null;

    static {
        sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sMatcher.addURI(Numa.AUTHORITY, "news", ID_NEWS);
        sMatcher.addURI(Numa.AUTHORITY, "news/#", ID_NEWS_ITEM);
        sMatcher.addURI(Numa.AUTHORITY, "feeds", ID_FEED);
        sMatcher.addURI(Numa.AUTHORITY, "feeds/#", ID_FEED_ITEM);
        sMatcher.addURI(Numa.AUTHORITY, "dialogs", ID_DIALOGS);
        sMatcher.addURI(Numa.AUTHORITY, "kvs", ID_KVS);
        sMatcher.addURI(Numa.AUTHORITY, "messages", ID_MESSAGES);
        sMatcher.addURI(Numa.AUTHORITY, "users", ID_USERS);
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    SQLiteDatabase getDatabase() {
        String uid = Settings.getUid();
        if (mHelper == null || !uid.equals(currUid)) {
            mHelper = new DatabaseHelper(getContext(), "numa" + uid + ".sqlite");
            currUid = uid;
        }
        return mHelper.getWritableDatabase();
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        SQLiteDatabase db = getDatabase();
        String tables = null;
        String groupBy = null;
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        String orderBy;
        if (TextUtils.isEmpty(sortOrder)) {
            orderBy = null;
        } else {
            orderBy = sortOrder;
        }
        Uri bindUri = null;
        switch (sMatcher.match(uri)) {
            case ID_NEWS:
                tables = Numa.NewsColumns.HOT_NEWS_TABLE_NAME;
                bindUri = uri;
                break;
            case ID_NEWS_ITEM:
                tables = Numa.NewsColumns.HOT_NEWS_TABLE_NAME;
                qb.appendWhere("_id=" + uri.getPathSegments().get(0));
                break;
            case ID_FEED:
                tables = Numa.FeedColumns.TABLE_NAME;
                bindUri = uri;
                break;
            case ID_FEED_ITEM:
                tables = Numa.FeedColumns.TABLE_NAME;
                qb.appendWhere("_id=" + uri.getPathSegments().get(0));
                break;
            case ID_DIALOGS:
                tables = Numa.DialogColumns.TABLE_NAME;
                bindUri = uri;
                break;
            case ID_KVS:
                tables = Numa.KeyValueColumns.TABLE_NAME;
                break;
            case ID_MESSAGES:
                tables = Numa.MessageColumns.TABLE_NAME;
                bindUri = uri;
                break;
            case ID_USERS:
                tables = Numa.UserColumns.TABLE_NAME;
                bindUri = uri;
                break;
        }
        if (TextUtils.isEmpty(tables)) {
            return null;
        }
        qb.setTables(tables);
        Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, null, orderBy);
        if (bindUri != null)
            c.setNotificationUri(getContext().getContentResolver(), bindUri);
        return c;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = getDatabase();
        String table = null;
        long rowId;
        int i = sMatcher.match(uri);
        Uri ret = null;
        switch (i) {
            case ID_NEWS:
                table = Numa.NewsColumns.HOT_NEWS_TABLE_NAME;
                break;
            case ID_FEED:
                table = Numa.FeedColumns.TABLE_NAME;
                break;
            case ID_DIALOGS: {
                table = Numa.DialogColumns.TABLE_NAME;
                long did = values.getAsLong("_id");
                if (db.update(table, values, "_id=" + did, null) == 0) {
                    db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
                }
            }
            return null;
            case ID_MESSAGES:
                table = Numa.MessageColumns.TABLE_NAME;
                break;
            case ID_USERS:
                table = Numa.UserColumns.TABLE_NAME;
                break;
        }
        if (table != null) {
            db.beginTransaction();
            rowId = db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
            db.setTransactionSuccessful();
            db.endTransaction();
            ret = ContentUris.withAppendedId(uri, rowId);
        }
        if (ret != null) {
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return ret;

    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        SQLiteDatabase db = getDatabase();
        switch (sMatcher.match(uri)) {
            case ID_DIALOGS: {
                db.beginTransaction();
                for (ContentValues value : values) {
                    long did = value.getAsLong("_id");
                    if (db.update(Numa.DialogColumns.TABLE_NAME, value, "_id=" + did, null) == 0) {
                        db.insertWithOnConflict(Numa.DialogColumns.TABLE_NAME, null, value, SQLiteDatabase.CONFLICT_REPLACE);
                    }
                }
                db.setTransactionSuccessful();
                db.endTransaction();
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return values.length;
            case ID_MESSAGES: {
                db.beginTransaction();
                for (ContentValues value : values) {
                    db.insertWithOnConflict(Numa.MessageColumns.TABLE_NAME, null, value, SQLiteDatabase.CONFLICT_REPLACE);
                }
                db.setTransactionSuccessful();
                db.endTransaction();
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return values.length;
            case ID_USERS: {
                db.beginTransaction();
                for (ContentValues value : values) {
                    db.insertWithOnConflict(Numa.UserColumns.TABLE_NAME, null, value, SQLiteDatabase.CONFLICT_REPLACE);
                }
                db.setTransactionSuccessful();
                db.endTransaction();
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return values.length;
        }
        return super.bulkInsert(uri, values);
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = getDatabase();
        int count = 0;
        String myWhere;
        Uri notifyUri = null;

        switch (sMatcher.match(uri)) {
            case ID_NEWS:
                count = db.delete(Numa.NewsColumns.HOT_NEWS_TABLE_NAME, where, whereArgs);
                notifyUri = Numa.NewsColumns.CONTENT_URI;
                break;
            case ID_NEWS_ITEM:
                myWhere = "_id=" + uri.getPathSegments().get(0) + (!TextUtils
                        .isEmpty(where) ? " AND (" + where + ")" : "");
                count = db.delete(Numa.NewsColumns.HOT_NEWS_TABLE_NAME, myWhere, whereArgs);
                notifyUri = Numa.NewsColumns.CONTENT_URI;
                break;
            case ID_FEED:
                count = db.delete(Numa.FeedColumns.TABLE_NAME, where, whereArgs);
                notifyUri = Numa.FeedColumns.CONTENT_URI;
                break;
            case ID_FEED_ITEM:
                myWhere = "_id=" + uri.getPathSegments().get(0) + (!TextUtils
                        .isEmpty(where) ? " AND (" + where + ")" : "");
                count = db.delete(Numa.FeedColumns.TABLE_NAME, myWhere, whereArgs);
                notifyUri = Numa.FeedColumns.CONTENT_URI;
                break;
        }
        if (notifyUri != null) {
            getContext().getContentResolver().notifyChange(notifyUri, null);
        }

        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int count = 0;
        String myWhere;
        SQLiteDatabase db = getDatabase();
        Uri notifyUri = null;
        switch (sMatcher.match(uri)) {
            case ID_NEWS:
                count = db.update(Numa.NewsColumns.HOT_NEWS_TABLE_NAME, values, selection,
                        selectionArgs);
                notifyUri = Numa.NewsColumns.CONTENT_URI;
                break;
            case ID_NEWS_ITEM:
                myWhere = "_id="
                        + uri.getPathSegments().get(0)
                        + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                        + ")" : "");
                count = db.update(Numa.NewsColumns.HOT_NEWS_TABLE_NAME, values, myWhere,
                        selectionArgs);
                notifyUri = Numa.NewsColumns.CONTENT_URI;
                break;
            case ID_FEED:
                count = db.update(Numa.FeedColumns.TABLE_NAME, values, selection,
                        selectionArgs);
                notifyUri = Numa.FeedColumns.CONTENT_URI;
                break;
            case ID_FEED_ITEM:
                myWhere = "_id="
                        + uri.getPathSegments().get(0)
                        + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                        + ")" : "");
                count = db.update(Numa.FeedColumns.TABLE_NAME, values, myWhere,
                        selectionArgs);
                notifyUri = Numa.FeedColumns.CONTENT_URI;
                break;
            case ID_DIALOGS:
                count = db.update(Numa.DialogColumns.TABLE_NAME, values, selection,
                        selectionArgs);
                notifyUri = Numa.DialogColumns.CONTENT_URI;
                break;
            case ID_MESSAGES:
                count = db.update(Numa.MessageColumns.TABLE_NAME, values, selection,
                        selectionArgs);
                notifyUri = Numa.MessageColumns.CONTENT_URI;
                break;
            case ID_KVS:
                count = db.update(Numa.KeyValueColumns.TABLE_NAME, values, selection,
                        selectionArgs);
                break;
            case ID_USERS:
                count = db.update(Numa.UserColumns.TABLE_NAME, values, selection,
                        selectionArgs);
                notifyUri = Numa.UserColumns.CONTENT_URI;
                break;
        }
        if (notifyUri != null) {
            getContext().getContentResolver().notifyChange(notifyUri, null);
        }
        return count;
    }
}
